package com.parenting.util;

import cn.hutool.core.bean.BeanUtil;
import com.parenting.exception.BaseException;
import com.parenting.model.ParentUserDTO;
import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import lombok.extern.slf4j.Slf4j;
import net.minidev.json.JSONObject;

import java.text.ParseException;
import java.util.Date;
import java.util.Objects;

/**
 * 小滴课堂,愿景：让技术不再难学
 *
 * @Description
 * @Author 二当家小D
 * @Remark 有问题直接联系我，源码-笔记-技术交流群
 * @Version 1.0
 **/

@Slf4j
public class JWTUtil {

    /**
     * 创建秘钥
     */
    private static final byte[] SECRET = "6MNSobBRCHGIO0fS6MNSobBRCHGIO0fS".getBytes();

        /**
     * token 过期时间，正常是1天
     */
    private static final long EXPIRE_TIME = 1000 * 60 * 60 * 24;


    /**
     * 生成Token
     * @param
     * @return
     */
    public static String buildJWT(ParentUserDTO loginUser,String jti) {
        try {
            /**
             * 1.创建一个32-byte的密匙
             */
            MACSigner macSigner = new MACSigner(SECRET);
            /**
             * 2. 建立payload 载体
             */
            JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
                    .subject("doi")
                    .issuer("http://www.doiduoyi.com")
                    .expirationTime(new Date(System.currentTimeMillis() + EXPIRE_TIME))
                    .claim("headPortrait", loginUser.getHeadPortrait())
                    .claim("userId", loginUser.getUserId())
                    .claim("nickname", loginUser.getNickname())
                    .claim("telephone",loginUser.getTelephone())
                    .claim("jti", jti)
                    .build();
            /**
             * 3. 建立签名
             */
            SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.HS256), claimsSet);
            signedJWT.sign(macSigner);
            /**
             * 4. 生成token
             */
            String token = signedJWT.serialize();
            return token;
        } catch (KeyLengthException e) {
            e.printStackTrace();
            return null;
        } catch (JOSEException e) {
            e.printStackTrace();
            return null;
        }

    }

    /**
     * 校验token
     * @param token
     * @return
     */
    public static ParentUserDTO vaildToken(String token ) {
        try {
            SignedJWT jwt = SignedJWT.parse(token);
            JWSVerifier verifier = new MACVerifier(SECRET);
            //校验是否有效
            if (!jwt.verify(verifier)) {
                throw new BaseException(-1, "Token 无效");
            }
            //校验超时
            Date expirationTime = jwt.getJWTClaimsSet().getExpirationTime();
            if (new Date().after(expirationTime)) {
                throw new BaseException(-2, "Token 已过期");
            }
            //获取载体中的数据
            JWSObject jwsObject = JWSObject.parse(token);
            JSONObject jsonObject = jwsObject.getPayload().toJSONObject();
            ParentUserDTO parentUserDTO = BeanUtil.copyProperties(jsonObject, ParentUserDTO.class);
            //是否有openUid
            if (Objects.isNull(parentUserDTO)){
                throw new BaseException(-3, "用户不存在");
            }
            return parentUserDTO;
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (JOSEException e) {
            e.printStackTrace();
        }
        return null;
    }


}
